package cc.rengu.igas.mcps.core.service.base;

import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.PublicService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.share.core.realize.impl.PublicServiceImpl;
import cc.rengu.igas.share.core.realize.impl.RiskMonitorServiceImpl;
import cc.rengu.oltp.service.base.BizBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.RiskMonitorInfo;
import cc.rengu.oltp.service.realize.RiskMonitorService;
import cc.rengu.oltp.utility.annotation.BIZ_AFTER;
import cc.rengu.oltp.utility.annotation.BIZ_BEFORE;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;

/**
 * 线上管理服务基类
 * Created by 王成 on 2018/4/17.
 */
public abstract class QrManageService extends BizBaseService {

    @Override
    protected Object beforeBizProcess() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String txnNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_NUM);
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String msgSrcId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.MSG_SRC_ID);

        /* Step1：查找BIZ_BEFORE的注解*/
        invokeBizAnnoMethod(BIZ_BEFORE.class);

        /* Step2：检查验签状态 */
        String verifySignFlag = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.VERIFY_SIGN_FLAG);
        if (AppParamConstant.NO.equals(verifySignFlag)) {
            throw new BizException(RespCodeEnum.VERIFY_SIGN_ERROR.getRespCode(), RespCodeEnum.VERIFY_SIGN_ERROR.getRespDesc());
        }

        /* Step3：检查Session是否存在 */
        String isLogin = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.IS_LOGIN);
        if (AppParamConstant.NO.equals(isLogin)) {
            throw new BizException(RespCodeEnum.SESSION_INVALID.getRespCode(), RespCodeEnum.SESSION_INVALID.getRespDesc());
        }

        /* Step4：检查接口合法性 */
        PublicService publicService = new PublicServiceImpl();
        publicService.checkInputValidity(msgSrcId, txnNum);
        publicService.checkInputParamLegal();

        /* Step5：检查商户合法性 */
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        if (!StringUtil.isEmptyOrNull(mchntNo)) {
            rglog.info("检查商户状态");
            MchntService mchntService = new MchntServiceImpl();
            boolean checkResult = mchntService.checkMchntStatus(instId, mchntNo);
            if (!checkResult) {
                rglog.error("商户<{}>不存在或者状态异常!", mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
            }
        }

        /* Step6：交易处理前客户化 */
        rglog.info("交易处理前客户化");
        return bizBeforeCust();
    }

    @Override
    protected BizResponse callBizService(Object request) throws Exception {
        /* Step1：公共业务处理 */

        /* Step2：查找BIZ_PROCESS的注解 */
        invokeBizAnnoMethod(BIZ_PROCESS.class);

        /* Step3：业务逻辑处理*/
        return bizProcessCust(request);
    }

    @Override
    protected void afterBizProcess(BizResponse response) throws Exception {
        /* Step1：业务调用后公共处理*/

        /* Step2：查找BIZ_AFTER的注解 */
        invokeBizAnnoMethod(BIZ_AFTER.class);

        /* Step3：业务调用后客户化处理 */
        bizAfterCust(response);
    }

    @Override
    protected RiskMonitorInfo getRiskMonitorInfo() {
        RiskMonitorInfo riskMonitorInfo = new RiskMonitorInfo();
        RiskMonitorService riskMonitorService = new RiskMonitorServiceImpl();
        riskMonitorInfo.setTransMonitor(riskMonitorService);
        return riskMonitorInfo;
    }

    /**
     * 业务处理前客户化处理
     *
     * @return 业务处理实体类
     */
    protected abstract Object bizBeforeCust() throws Exception;

    /**
     * 业务逻辑处理客户化处理
     *
     * @param request 业务处理前的返回实体类
     * @return 业务处理结果
     */
    protected abstract BizResponse bizProcessCust(Object request) throws Exception;

    /**
     * 业务处理后逻辑处理
     *
     * @param response 业务调用响应信息
     */
    protected abstract void bizAfterCust(Object response) throws Exception;
}
